package com.example;

import com.example.jni.MouseListenerJNI;
import com.github.kwhat.jnativehook.GlobalScreen;
import com.github.kwhat.jnativehook.NativeHookException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static com.example.CaptureProperty.isCaptureActive;

/**
 * 项目编码问题会导致graalvm打包失败，
 * graalvm默认是GBK编码，
 * 将除了自写代码的编码可以为UTF-8，其它文件编码改为GBK，即项目编码应为GBK
 */
public class App extends Application implements KeyEventBroadCast.KeyEventListener {

    private CutAction cutAction;
    private PaneManager paneManager;
    
    /**
     * 启动<br/>
     * 使用主窗口创建一个无任务图标窗口，然后子窗口运行截图逻辑来避免出现任务栏图标
     * 参考：
     * <a href="https://stackoverflow.com/questions/46712293/how-can-i-remove-my-javafx-program-from-the-taskbar">
     *     How can I remove my javafx program from the taskbar
     * </a>
     * @param primaryStage 程序主窗口
     * @throws Exception
     */
    @Override
    public void start(Stage primaryStage) throws Exception {
        // 创建一个无任务图标窗口。
        // StageStyle.UTILITY无任务图标但有边框，
        // StageStyle.TRANSPARENT无边框但有任务图标，结合二者实现无任务图标无边框效果
        primaryStage.initStyle(StageStyle.UTILITY);
        primaryStage.setOpacity(0);
        primaryStage.setHeight(0);
        primaryStage.setWidth(0);
        primaryStage.setAlwaysOnTop(true);
        primaryStage.show();
        // 初始化窗体布局
        paneManager = new PaneManager(primaryStage);
        cutAction = new CutAction(primaryStage, paneManager);
        
        // 关闭窗口时不结束运行
        Platform.setImplicitExit(false);
        // 任务栏图标
//        primaryStage.getIcons().add(new javafx.scene.image.Image("image/icon.png"));
        trayManagement();
        // 监听全局键盘快捷键
        listenGlobalKeyEvent();

        // 注册截图事件监听器
        KeyEventBroadCast.getInstance().addListener(this);

    }

    /**
     * 托盘管理
     */
    public void trayManagement() {
        if (SystemTray.isSupported()) {
            SystemTray tray = SystemTray.getSystemTray();
            // 用相对于项目根目录的绝路名称路径（带"/"）来找图片
            Image image = Toolkit.getDefaultToolkit().getImage(App.class.getResource("/image/icon.png"));

            TrayIcon trayIcon = new TrayIcon(image, "Screen Shot App");
            trayIcon.setImageAutoSize(true);

            MenuItem cutItem = new MenuItem("截图");
            MenuItem exitItem = new MenuItem("退出");
            // ActionListener中的代码运行于子线程，
            // 和系统解界面交互时需使用Platform.runLater确保操作代码运行于JavaFX Application Thread
            cutItem.addActionListener(cutAction);
            exitItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 关闭线程池
                    paneManager.getToolbarManager().closeThreadPool();
                    // 卸载全局鼠标监听钩子
                    MouseListenerJNI.getInstance().UninstallMouseHook();
                    Platform.exit();
                    System.exit(0);
                }
            });

            PopupMenu popup = new PopupMenu();
            popup.add(cutItem);
            popup.add(exitItem);

            trayIcon.setPopupMenu(popup);

            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 全局事件监听要运行于JavaFX Application Thread才能在javafx程序运行时监听到事件
     */
    private void listenGlobalKeyEvent() {
        // 监听键盘
        try {
            GlobalScreen.registerNativeHook();
        }
        catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }
        GlobalScreen.addNativeKeyListener(new GlobalKeyListener());
    }

    public static void main(String[] args) {
        System.out.println("Hello World!");
        launch(args);
        
    }

    @Override
    public void onScreenShotRequested() {
        if (isCaptureActive) {
            System.out.println("截图已在进行中，忽略请求");
            return;
        }
        isCaptureActive = true;
        System.out.println("开始处理截图请求");
        // 在JavaFX线程中执行截图操作
        Platform.runLater(() -> {
            // 创建ActionEvent模拟托盘菜单点击
            ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "SCREENSHOT");
            cutAction.actionPerformed(event);
        });
    }

    @Override
    public void closeScreenShot() {
        if (isCaptureActive) {
            Platform.runLater(() -> {
                paneManager.getToolbarManager().closeCurrentWindow();
            });
        }
    }
    
}
